/*
 * Game 0.0.1 - 游戏主功能类
 *
 * Copyright (c) 2008 Dalton (9wee.com)
 *
 *
 * $Date: 2008-12-25 $
 * $Rev: 01 $
 *
 --------------------------------------------------
 更新日志
 要考虑太多兼容性的东西，实在有够烦！

 */
function Game(_desk, _width, _height){//游戏容器，地图对象，地图图片

	var self = this;
	//主场景
	this.desk = _desk;
	//当前用户
	this.curUser = null;
	//当前场景
	this.sceneId = null;

	//场景CSS
	this.desk.style.position = "relative";
	this.desk.style.width = _width + "px";
	this.desk.style.height = _height + "px";
	this.desk.style.overflow = "hidden";
	this.desk.style.visibility = "hidden";


	this.width = _width;
	this.height = _height;
	this.g_map = null;

	try{//IE6背景图片缓存
		if(browser.msie) document.execCommand("BackgroundImageCache", false, true);
	}catch(e){}

	//载入地图
	this.loadMap = function(_gw, _gh, _libs, _maps_bg, _maps_it, _speed, _delay) {
		this.g_map = new gameMap(_gw, _gh, _libs, _maps_bg, _maps_it);
		this.g_map.setMap();

		//删除原来的containner
		if (!!dom.getById("g_container")) {
			dom.removeNodes(dom.getById("g_container"));
		}

		this.desk.appendChild(this.g_map.container.domObj);
		this.desk.style.visibility = "visible";
		this.speed = _speed;
		this.delay = _delay;
	};

	//游戏物件对象
	var gameObj = function(_oname, _width, _height, _bgsrc, _x, _y, _left, _top, _zindex){

		var obj = document.createElement("DIV");
		obj.setAttribute("id",(_oname||''));
		if (_width) {
			obj.style.width = _width + "px";
		}
		if (_height) {
			obj.style.height = _height + "px";
		}
		obj.style.overflow = 'hidden';
		obj.style.position = 'absolute';
		obj.style.left = (_left||0)+"px";
		obj.style.top = (_top||0)+"px";
		obj.setAttribute("x",(_left||0));
		obj.setAttribute("y",(_top||0));
		obj.setAttribute("speed",10);
		obj.setAttribute("delay",100);
		obj.style.zIndex = _zindex||0;

		if(_bgsrc!=''){
			obj.style.background = 'url('+_bgsrc+') '+(_x||0)+'px '+(_y||0)+'px no-repeat';
		}

		this.domObj = obj;
	}

	gameObj.prototype = {
		setAtt:function(_ptArr){
			if(_ptArr.length>0){
				var ptN='',ptV='';
				for(var i=0;i<_ptArr.length;i++){
					ptN = _ptArr[i][0];
					ptV = _ptArr[i][1];
					this.domObj.setAttribute(ptN,ptV);
				}
			}
		},
		getAtt:function(att){
			return this.domObj.getAttribute(att);
		},
		scroll2:function(x1,y1){
			movePos(this.domObj, this.getAtt('x'), this.getAtt('y'), x1, y1, this.getAtt('speed'), this.getAtt('delay'));
		},
		stopScroll:function(){
			window.clearTimeout(this.domObj.timer);
			this.domObj.timer = null;
		}
	}

	//游戏地图对象
	var gameMap = function(_gw, _gh, _libs, _maps_bg, _maps_it){
		this.g_width = _gw;		//格子宽
		this.g_height = _gh;		//格子高
		this.g_libs = _libs;		//物品对象
		this.g_maps_bg = _maps_bg;	//地图背景
		this.g_maps_it = _maps_it;	//地图物品
		this.g_flag = [];		//通行、障碍
		this.container = null;		//地图、物品容器对象
		this.maptable = null;		//地图对象
	}

	gameMap.prototype = {
		//创建地图及物品
		setMap: function() {
			var gMaps = this.g_maps_bg;
			var iMaps = this.g_maps_it;
			var gLibs = this.g_libs;
			var rl = gMaps.length;			//行
			if(rl > 0 ){
				var cl = gMaps[0].length;	//列
				var gw = this.g_width;		//格子宽
				var gh = this.g_height;		//格子宽
				var maxw = gw * cl;		//地图宽度
				var maxh = gh * rl;		//地图高度
				this.container = new gameObj('g_container', 0, 0, '', 0, 0, 0, 0, 0);
				this.container.setAtt([['width',maxw],['height',maxh],['speed',50],['delay',10]]);
				var tdStr = '<tr>'+new Array(cl+1).join('<td></td>')+'</tr>';
				var trStr = new Array(rl+1).join(tdStr);
				var tableStr = '<table border="0" cellspacing="0" cellpadding="0" style="width:'+maxw+'px;height:'+maxh+'px;">'+trStr+'</table>';
				var cdom = this.container.domObj;
				cdom.innerHTML = tableStr;

				var mapTable = this.maptable = this.container.domObj.childNodes[0];

				var gflag=[],nCell=null,putbg=null,childBg=null,bgc=0,itc=0,putItem=null,childItem=null,ix=0,iy=0;
				for(var i=0; i<rl; i++){
					gflag[i] = [];
					for(var n=0; n<cl; n++){
						nCell = mapTable.rows[i].cells[n];
						putbg = gLibs['item_'+gMaps[i][n][0]];	//该位置需要放置的背景
						bgc = gMaps[i][n][1];
						childBg = putbg.child[bgc]
						nCell.style.width = gw + "px";
						nCell.style.height = gh + "px";
						nCell.style.background = 'url('+putbg.u+') '+childBg.x+'px '+childBg.y+'px no-repeat';
						gflag[i][n] = childBg.f;
						if(iMaps[i][n] != null){
							//如果是三层结构的话
							if (iMaps[i][n][0].constructor == Array) {

								putItem0 = gLibs['item_'+iMaps[i][n][0][0]];	//该位置需要放置的物品
								itc0 = iMaps[i][n][0][1];
								childItem0 = putItem0.child[itc0];

								putItem1 = gLibs['item_'+iMaps[i][n][1][0]];	//该位置需要放置的物品
								itc1 = iMaps[i][n][1][1];
								childItem1 = putItem1.child[itc1];

								gflag[i][n] = childItem1.f;

								nCell.innerHTML = '<div style="display:block;width:'+gw+'px;height:'+gh+'px;background:url('+putItem0.u+') '+childItem0.x+'px '+childItem0.y+'px no-repeat;z-index:'+ childItem0.z +';position:relative;" title="'+putItem0.n+'"><div style="display:block;width:'+gw+'px;height:'+gh+'px;background:url('+putItem1.u+') '+childItem1.x+'px '+childItem1.y+'px no-repeat;z-index:'+ childItem1.z +';" title="'+putItem1.n+'"></div></div>';

							}
							else {
								putItem = gLibs['item_'+iMaps[i][n][0]];	//该位置需要放置的物品
								itc = iMaps[i][n][1];
								childItem = putItem.child[itc];
								gflag[i][n] = childItem.f;
								var aDom = document.createElement("div");
								aDom.style.display = "block";
								aDom.style.width = gw + 'px';
								aDom.style.height = gh + 'px';
								aDom.style.background = 'url(' + putItem.u + ') ' + childItem.x + 'px ' + childItem.y + 'px no-repeat';
								aDom.style.zIndex = childItem.z;
								aDom.style.position = "relative";
								aDom.title = putItem.n;
								if (childItem.a != undefined) {
									var clickEvent = new Event();
									clickEvent.funcName = childItem.a.flag;
									clickEvent.parmas = childItem.a.params;
									aDom.action = clickEvent.callFunction.bind(clickEvent);
								}
								nCell.appendChild(aDom);
							}

						}
					}
				}
				this.g_flag = gflag.slice(0);
				gflag = [];
			}
		}
	};


	//缓慢移动地图视角
	function movePos(obj,x0,y0,x1,y1,speed,delay){

		if(x0==x1 && y0 ==y1){
			window.clearTimeout(obj.timer);
			obj.timer = null;
			return;
		}
		var x = Math.abs(x0-x1);
		var y = Math.abs(y0-y1);
		var s = Math.sqrt(x*x+y*y);
		var sx = speed * (x/s);
		var sy = speed * (y/s);
		x0 = (x0<x1)?Math.floor(x0/1+sx/1):Math.floor(x0/1-sx/1);
		y0 = (y0<y1)?Math.floor(y0/1+sy/1):Math.floor(y0/1-sy/1);

		if(x<sx){x0 = x1;}
		if(y<sy){y0 = y1;}

		obj.style.left = x0+"px";
		obj.style.top = y0+"px";
		obj.setAttribute('x',x0);
		obj.setAttribute('y',y0);
		obj.timer = window.setTimeout(function(){movePos(obj,x0,y0,x1,y1,speed,delay)},delay);
	}

	//得到地图需移动的偏移量
	function moveview(x, y){

		var v_w = self.width/1;
		var v_h = self.height/1;
		var m_w = self.g_map.container.getAtt('width')/1;
		var m_h = self.g_map.container.getAtt('height')/1;
		var o_l = self.g_map.container.getAtt('x')/1;
		var o_t = self.g_map.container.getAtt('y')/1;

		var blockx = (x*32 + o_l)/32;
		var blocky = (y*32 + o_t)/32;
		self.g_map.container.stopScroll();

		var x1=0, y1=0;

		//暂时先算X的偏移，Y的话同理
		if (blockx >= 24) {
			x1 = o_l - 23*32;
			if (x1 + m_w < v_w) {
				x1 = v_w - m_w;
			}
		}

		if (blockx <= 1) {
			x1 = o_l + 23*32;
			if (x1 < v_w) {
				x1 = 0;
			}
		}

		if (blocky <= 1 || blocky >= 18 || blockx <= 1 || blockx >= 24) {
			self.g_map.container.scroll2(x1,y1);
		} else{
			self.g_map.container.stopScroll();
		}
	}
	//停止移动
	function stopmv(){
		self.g_map.container.stopScroll();
	}


	this.users = {};
	this.addUser = function(_name, _src, _width, _height, _x, _y, _speed, _anidelay){
		var newuser = new user(_name, _src, _width, _height, _x, _y, _speed, _anidelay);
		this.users[_name] = newuser;
		this.g_map.container.domObj.appendChild(newuser.human);
	}

	this.removeUser = function(_name) {
		dom.removeNodes(dom.getById(_name));
		dom.removeNodes(dom.getById("mapFlag-" + _name));
	}

	this.clearMinimap = function() {
		dom.emptyNodes(dom.getById("minimap"));
	}

	//人物图片，宽，高，起始X坐标，起始Y坐标，移动速度，动画效果间隔时间
	function user(_name, _src, _width, _height, _x, _y, _speed, _anidelay){
		this.name = _name;
		this.speed = _speed;
		this.anidelay = _anidelay;
		this.width = _width;
		this.height = _height;
		this.x = _x*32;
		this.y = _y*32;
		this.bx = _x;
		this.by = _y;
		this.direction = 0;
		this.timer = null;
		this.timer2 = null;

		//user层
		var newuser = document.createElement("div");
		newuser.id = _name;
		newuser.className = "user";
		newuser.style.left = this.x + 'px';
		newuser.style.top = this.y + 'px';

		//user的人物名称层
		newuserName = document.createElement("span");
		newuserName.innerHTML = _name;
		newuserName.className = "userName";


		//user的图片人物层
		newuserImage = document.createElement("div");
		newuserImage.style.width = _width + 'px';
		newuserImage.style.height = _height + 'px';
		newuserImage.className = "userImage";
		newuserImage.style.background = "url(" + _src + ") 0 0 no-repeat";

		//user的人物信息盒
		newuserMessage = document.createElement("div");
		newuserMessage.id = 'messageBox-' + _name;
		newuserMessage.className = 'messageBox';
		newuserMessage.style.left = 32 + 'px';
		newuserMessage.style.top = -60 + 'px';
		newuserMessage.style.visibility = "hidden";

		//user的迷你地图位置
		newuserminimap = document.createElement("div");

		if (_name == mygame.curUser)
			newuserminimap.className = 'mapCurFlag';
		else
			newuserminimap.className = 'mapFlag';
		newuserminimap.id = 'mapFlag-' + _name;
		newuserminimap.style.left = this.bx*95/32 + 'px';
		newuserminimap.style.top = this.by*75/18 + 'px';

		dom.getById("minimap").appendChild(newuserminimap);


		newuser.appendChild(newuserImage);
		newuser.appendChild(newuserName);
		newuser.appendChild(newuserMessage);

		this.human = newuser;
		this.human.image = newuserImage;
		return this;
	}

	//执行移动
	user.prototype.moveUser = function(x1, y1, path, obj){
		this.stop();
		this.getdir(x1,y1);
		this.gotopos(x1,y1, path, obj);
	}

	//获取方向
	user.prototype.getdir = function(x1, y1){
		var x0 = this.x;
		var y0 = this.y;
		var _angle = Math.ceil(angle(x0, y0, x1, y1));

		if(255<_angle && _angle<285){
			this.direction = 0;//6点钟方向
		}
		if(195<_angle && _angle<255){
			this.direction = 1;//7、8点钟方向
		}
		if(165<_angle && _angle<195){
			this.direction = 2;//9点钟方向
		}
		if(105<_angle && _angle<165){
			this.direction = 3;//10、11点钟方向
		}
		if(75<_angle && _angle<105){
			this.direction = 4;//12点钟方向
		}
		if(15<_angle && _angle<75){
			this.direction = 5;//1、2点钟方向
		}
		if(_angle<15 || _angle>345){
			this.direction = 6;//3点钟方向
		}
		if(285<_angle && _angle<345){
			this.direction = 7;//4、5点钟方向
		}
	}

	//求倾斜角
	function angle(x0, y0, x1, y1) {
		var x = x1 - x0;
		var y = y0 - y1;
		var _angle = Math.atan(y/x)*(180/Math.PI);
		if(x < 0) {
			return _angle + 180;
		}else if(y < 0) {
			return _angle + 360;
		}
		return _angle;
	}

	//获取动画贴图Y坐标
	user.prototype.getposY = function() {
		var _y;
		switch(this.direction){
			case 0: _y = 0;break;//6点钟方向
			case 1: _y = 0;break;//7、8点钟方向
			case 2: _y = this.height*-1;break;//9点钟方向
			case 3: _y = this.height*-3;break;//10、11点钟方向
			case 4: _y = this.height*-3;break;//12点钟方向
			case 5: _y = this.height*-3;break;//1、2点钟方向
			case 6: _y = this.height*-2;break;//3点钟方向
			default: _y = 0;break;//4、5点钟方向
		}
		return _y;
	}

	//动画效果
	function moveani(obj, x1, y1) {
		this.moveobj = obj;
		this.gmx = 0;
		this.gmy = this.moveobj.getposY();

		//人物动画
		this.ani = function(){
			if(Math.abs(this.gmx) >= obj.width*2){
				this.gmx = 0;
			}else{
				this.gmx -= obj.width;
			}
			this.moveobj.human.image.style.backgroundPosition = this.gmx + "px "+this.gmy + "px";
		}

		this.x0 = this.moveobj.x;
		this.y0 = this.moveobj.y;
		this.tx = (x1 - this.x0);
		this.ty = (y1 - this.y0);

		//当前步进
		this.curStep = 0;
		//距离
		this.steps = Math.sqrt(Math.pow(this.tx, 2) + Math.pow(this.ty, 2));

		//人物移动
		this.move = function(path, obj){
			this.curStep += this.moveobj.speed/10;
			var x2 = this.tx * (this.curStep/this.steps) + this.x0;
			var y2 = this.ty * (this.curStep/this.steps) + this.y0;

			this.moveobj.human.style.left = x2 + "px";
			this.moveobj.human.style.top = y2 + "px";
			this.moveobj.x = x2;
			this.moveobj.y = y2;
			this.moveobj.by = Math.round(this.moveobj.y/32);
			this.moveobj.bx = Math.round(this.moveobj.x/32);

			//迷你地图的移动
			if (!!dom.getById("mapFlag-" + this.moveobj.name)) {
				dom.getById("mapFlag-" + this.moveobj.name).style.left = this.moveobj.bx*95/32 + 'px';
				dom.getById("mapFlag-" + this.moveobj.name).style.top = this.moveobj.by*75/18 + 'px';
			}
			//到达目的地
			if(this.curStep >= this.steps){
				this.moveobj.stop();
				this.moveobj.movePath(path, obj);
			}
		}
	}

	//两点间移动
	user.prototype.gotopos = function(x1, y1, path, obj){
		var gm = new moveani(this, x1, y1);
		function playani() {
			gm.ani();
			gm.moveobj.timer1 = window.setTimeout(playani, gm.moveobj.anidelay);
		}
		function movepos() {
			gm.move(path, obj);
		}
		playani();
		//30好像是最好的
		this.timer2 = window.setInterval(movepos, 30);

	}

	user.prototype.movePath = function(path, obj) {
		if(path.length > 0){
			pos = path.shift();
			this.moveUser(pos[1]*32, pos[0]*32, path, obj);

		}
		else {
			this.stop();
			if (this.name == mygame.curUser) {
				//执行地图点的动作
				if (obj != undefined && typeof obj.action == "function") {
					obj.action();
				}
				//移动视角
				if (typeof pos != "undefined")
				moveview(pos[1], pos[0]);
			}

		}
	};

	//停止
	user.prototype.stop = function() {
		window.clearTimeout(this.timer1);
		this.timer1 = null;
		window.clearInterval(this.timer2);
		this.timer2 = null;
		var _y = this.getposY();
		this.human.style.backgroundPosition = "0px " + _y + "px";
		return;
	};

	function setpos(e) {
		e = e||window.event;
		var obj = e.srcElement||e.target;

		var x = e.clientX||e.pageX;
		var y = e.clientY||e.pageY;


		var targetx = Math.floor((x - mygame.g_map.container.domObj.offsetLeft - mygame.desk.offsetLeft)/32);
		var targety = Math.floor((y - mygame.g_map.container.domObj.offsetTop - mygame.desk.offsetTop)/32);

		var path = window.astar.getPath(mygame.users[mygame.curUser].by, mygame.users[mygame.curUser].bx, targety, targetx);
		if (path.length != 0)
			gameSocket.send("Z|U_" + mygame.sceneId + "|" + path[path.length-1][1] + "_" + path[path.length-1][0]);
		mygame.users[mygame.curUser].movePath(path, obj);
	}


	//设置事件监听
	this.setEvent = function() {

		//发送消息事件
		eve.observe(dom.getById("chatContent"), 'keydown', function() {
			var event = arguments[0] || window.event;
			var obj = event.srcElement||event.target;
			var post_content = obj.value;
			if (event.keyCode == 13) {
				gameSocket.send('W|' + post_content);
				obj.value = "";
			}

		});
		//点击寻路&移动事件
		eve.observe(this.desk, 'click', setpos);
	}
}